package plug_inregistryenhancements;

import java.util.WeakHashMap;
import java.util.concurrent.atomic.AtomicBoolean;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IViewPart;
import org.eclipse.ui.IWindowListener;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.IWorkbenchWindow;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.progress.UIJob;
import org.osgi.framework.BundleContext;

/**
 * The activator class controls the plug-in life cycle
 */
public class Activator extends AbstractUIPlugin {

	// The plug-in ID
	public static final String PLUGIN_ID = "Plug_inRegistryEnhancements";

	// The shared instance
	private static Activator plugin;
	
	private AtomicBoolean actionsRegistered = new AtomicBoolean(false);

	/**
	 * The constructor
	 */
	public Activator() {
	}
	
	void registerActions() {
		if (actionsRegistered.compareAndSet(false, true)) {
			UIJob uijob = new UIJob("") {
				@Override
				public IStatus runInUIThread(IProgressMonitor monitor) {
					// Add pulldown action to the view that may be already present in
					// exiting Workbench windows.
					IWorkbenchWindow[] workbenchWindows = PlatformUI.getWorkbench()
							.getWorkbenchWindows();
					for (IWorkbenchWindow workbenchWindow : workbenchWindows) {
						processWindow(workbenchWindow);
					}
	
					// Monitor future Workbench windows
					PlatformUI.getWorkbench().addWindowListener(new IWindowListener() {
						public void windowActivated(IWorkbenchWindow window) {
						}
	
						public void windowClosed(IWorkbenchWindow window) {
						}
	
						public void windowDeactivated(IWorkbenchWindow window) {
						}
	
						public void windowOpened(IWorkbenchWindow window) {
							processWindow(window);
						}
					});
					return Status.OK_STATUS;
				}
			};
			uijob.setPriority(UIJob.INTERACTIVE);
			uijob.schedule();
		}
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext
	 * )
	 */
	public void start(BundleContext context) throws Exception {
		super.start(context);
		plugin = this;
		
		registerActions();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext
	 * )
	 */
	public void stop(BundleContext context) throws Exception {
		plugin = null;
		super.stop(context);
	}

	/**
	 * Returns the shared instance
	 * 
	 * @return the shared instance
	 */
	public static Activator getDefault() {
		return plugin;
	}

	/**
	 * Returns an image descriptor for the image file at the given plug-in relative path.
	 * 
	 * @param path
	 *            the path
	 * @return the image descriptor
	 */
	public static ImageDescriptor getImageDescriptor(String path)
	{
		return AbstractUIPlugin.imageDescriptorFromPlugin(PLUGIN_ID, path);
	}
	
	private static WeakHashMap<IViewPart, Boolean> actionsAddedToView = new WeakHashMap<IViewPart, Boolean>();

	private static void addActions(IViewPart viewPart) {
		Boolean added = (Boolean) actionsAddedToView.get(viewPart);
		if (added == null) {
			// The actions were not added yet
			final IToolBarManager toolBarManager = viewPart.getViewSite()
					.getActionBars().getToolBarManager();
			OpenActions action = new OpenActions();
			action.init(viewPart);
			toolBarManager.add(action); //$NON-NLS-1$

			toolBarManager.update(true);
			actionsAddedToView.put(viewPart, Boolean.TRUE);
		}
	}

	// Listner for monitoring the view opening
	private static final IPartListener partListener = new IPartListener() {

		public void partOpened(IWorkbenchPart part) {
			if (part instanceof IViewPart) {
				IViewPart viewPart = (IViewPart) part;
				if ("org.eclipse.pde.runtime.RegistryBrowser".equals(viewPart
						.getSite().getId())) {
					addActions(viewPart);
				}
			}
		}

		public void partClosed(IWorkbenchPart part) {
			if (part instanceof IViewPart) {
				IViewPart viewPart = (IViewPart) part;
				if ("org.eclipse.pde.runtime.RegistryBrowser".equals(viewPart
						.getSite().getId())) {
					// forget the view's actions added state
					actionsAddedToView.remove(viewPart);
				}
			}
		}

		public void partActivated(IWorkbenchPart part) {

		}

		public void partBroughtToTop(IWorkbenchPart part) {

		}

		public void partDeactivated(IWorkbenchPart part) {
		}
	};

	private static void processWindow(IWorkbenchWindow window) {
		IWorkbenchPage[] pages = window.getPages();
		for (IWorkbenchPage workbenchPage : pages) {
			IViewPart viewPart = workbenchPage
					.findView("org.eclipse.pde.runtime.RegistryBrowser");
			if (viewPart != null && viewPart.getSite() != null) {
				addActions(viewPart);
				break;
			}
		}

		// Monitor furture view creation in case the view
		// is closed and reopened
		window.getPartService().addPartListener(partListener);
	}
}
